package com.dev.op.config;

import com.dev.op.entity.User;
import com.dev.op.enums.ResultCode;
import com.dev.op.exceptions.BizException;
import com.dev.op.util.JWTUtil;
import com.dev.op.util.RedisUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@Component
public class JWTAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        String authHeader = request.getHeader("Authorization");

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            try {
                //先检查 Redis 中是否存在 token（是否有效）
                boolean tokenValid = redisUtil.isTokenValid(token);
                //无效： 过期 /  token无效 需要重新登录拿token
                if (!tokenValid) {
                    throw new BizException(ResultCode.UNAUTHORIZED.code(), "登录状态已过期，请重新登录");
                }
                //如果有效的话，就加速JWT解析过程，直接从redis里面拿信息
                //解析 JWT 拿到用户信息和角色
                User user = jwtUtil.parseJWT(token);
                List<String> roles = jwtUtil.getUserRoles(token);
                //组装权限对象并注入 Spring Security 上下文
                List<SimpleGrantedAuthority> authorities = roles.stream()
                        .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
                        .toList();
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(user, null, authorities);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                // 刷新 token 有效时间
                //redisUtil.refresh("login:" + token, Duration.ofSeconds(24));
            } catch (Exception e) {
                //filter 发生的错误，可以认为是 请求方出现了问题，不做处理咯
            }
        }

        // 放行请求
        filterChain.doFilter(request, response);
    }
}